package main

import (
	"crypto/tls"
	"fmt"
	"log"
	"net"
	"net/smtp"
	"os"
	"time"

	"golang.org/x/crypto/ssh/terminal"
)

func main() {
	var (
		username string
		password string
		ip       string
		from     string
		to       string
		subject  string
		body     string
	)

	fmt.Print("Enter username: ")
	fmt.Scanln(&username)
	fmt.Print("Enter password: ")
	password = readPassword()
	fmt.Println() // Add a newline after reading the password

	fmt.Print("Enter access IP: ")
	fmt.Scanln(&ip)
	fmt.Print("Enter sender email (from): ")
	fmt.Scanln(&from)
	fmt.Print("Enter recipient email (to): ")
	fmt.Scanln(&to)
	fmt.Print("Enter subject: ")
	fmt.Scanln(&subject)
	fmt.Print("Enter message body: ")
	fmt.Scanln(&body)

	err := sendEmailSSL(username, password, ip, from, to, subject, body)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("Email sent successfully.")
}

// readPassword reads a password from the console without echoing input.
func readPassword() string {
	bytePassword, err := terminal.ReadPassword(int(os.Stdin.Fd()))
	if err != nil {
		panic(err)
	}
	return string(bytePassword)
}

// sendEmailSSL sends an email using SMTPS (SMTP over SSL) on port 465.
func sendEmailSSL(username, password, ip, from, to, subject, body string) error {
	auth := smtp.PlainAuth("", username, password, ip)

	message := fmt.Sprintf("From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n%s", from, to, subject, body)

	smtpAddr := fmt.Sprintf("%s:%d", ip, 465)
	dialer := net.Dialer{
		Timeout: time.Duration(30 * time.Second),
	}
	conn, err := dialer.Dial("tcp", smtpAddr)
	if err != nil {
		return err
	}
	defer conn.Close()

	tlsConfig := &tls.Config{
		InsecureSkipVerify: true, // For testing purposes only; remove or configure properly for production use
		ServerName:         ip,
	}

	tlsConn := tls.Client(conn, tlsConfig)
	if err := tlsConn.Handshake(); err != nil {
		return err
	}

	client, err := smtp.NewClient(tlsConn, ip)
	if err != nil {
		return err
	}
	defer client.Quit()

	if err = client.Auth(auth); err != nil {
		return err
	}

	if err = client.Mail(from); err != nil {
		return err
	}
	if err = client.Rcpt(to); err != nil {
		return err
	}

	w, err := client.Data()
	if err != nil {
		return err
	}
	_, err = w.Write([]byte(message))
	if err != nil {
		return err
	}
	err = w.Close()
	if err != nil {
		return err
	}

	return nil
}
